#include "toplevel_wrapper.h"
#include "wlroots-full.hpp"
#include "server.h"

ToplevelWrapper::ToplevelWrapper(struct wlr_xdg_surface *xdg_surface, Server *server)
    : m_xdg_surface(xdg_surface)
    , m_server(server)
{
    m_xdg_toplevel = m_xdg_surface->toplevel;
    m_scene_tree = wlr_scene_xdg_surface_create(
        &m_server->m_scene->tree, m_xdg_toplevel->base);
    m_scene_tree->node.data = this;
    m_xdg_surface->data = m_scene_tree;

    m_map.connect(&m_xdg_surface->surface->events.map, [=](void* data) {
        map();
    });

    m_unmap.connect(&m_xdg_surface->surface->events.unmap, [=](void* data) {
        unmap();
    });

    m_destroy.connect(&m_xdg_surface->events.destroy, [=](void* data) {
        destroy();
    });

    m_request_move.connect(&m_xdg_toplevel->events.request_move, [=](void* data) {
        request_move();
    });

    m_request_resize.connect(&m_xdg_toplevel->events.request_resize, [=](void* data) {
        struct wlr_xdg_toplevel_resize_event *event = (struct wlr_xdg_toplevel_resize_event*)data;
        request_resize(event);
    });

    m_request_maximize.connect(&m_xdg_toplevel->events.request_maximize, [=](void* data) {
        request_maximize();
    });

    m_request_fullscreen.connect(&m_xdg_toplevel->events.request_fullscreen, [=](void* data) {
        request_fullscreen();
    });
}

ToplevelWrapper::~ToplevelWrapper()
{

}

void ToplevelWrapper::move_toplevel_to_front()
{
    wlr_scene_node_raise_to_top(&m_scene_tree->node);
    // wl_list_remove(&toplevel->link);
    // wl_list_insert(&server->toplevels, &toplevel->link);
}

void ToplevelWrapper::activate()
{
    wlr_xdg_toplevel_set_activated(m_xdg_toplevel, true);
}

wlr_surface *ToplevelWrapper::base_surface()
{
    return m_xdg_toplevel->base->surface;
}

void ToplevelWrapper::set_position(int x, int y)
{
    wlr_scene_node_set_position(&m_scene_tree->node, x, y);
}

void ToplevelWrapper::set_size(int w, int h)
{
    wlr_xdg_toplevel_set_size(m_xdg_toplevel, w, h);
}

struct wlr_box ToplevelWrapper::get_base_geometry()
{
    struct wlr_box geo_box;
    wlr_xdg_surface_get_geometry(m_xdg_toplevel->base, &geo_box);
    return geo_box;
}

void ToplevelWrapper::map()
{
    m_server->m_toplevels.push_back(this);
    sig_toplevel_map.emit(this, base_surface());
}

void ToplevelWrapper::unmap()
{
    sig_toplevel_unmap.emit(this);
    // wl_list_remove(&toplevel->link);
}

void ToplevelWrapper::destroy()
{
#if 0
    wl_list_remove(&toplevel->map.link);
    wl_list_remove(&toplevel->unmap.link);
    wl_list_remove(&toplevel->destroy.link);
    wl_list_remove(&toplevel->request_move.link);
    wl_list_remove(&toplevel->request_resize.link);
    wl_list_remove(&toplevel->request_maximize.link);
    wl_list_remove(&toplevel->request_fullscreen.link);

    m_map.disconnect();
    m_unmap.disconnect();
    m_destroy.disconnect();

    free(toplevel);
#endif
}

void ToplevelWrapper::request_move()
{
    sig_toplevel_request_move.emit(this);
}

void ToplevelWrapper::request_resize(struct wlr_xdg_toplevel_resize_event* event)
{
    sig_toplevel_request_resize.emit(this, event->edges);
}

void ToplevelWrapper::request_maximize()
{
    sig_toplevel_request_maximize.emit(this);
}

void ToplevelWrapper::request_fullscreen()
{
    sig_toplevel_request_fullscreen.emit(this);
}
